package com.mylib.libcore.utils.crc;


import java.io.UnsupportedEncodingException;

/**
  * @Description: rc4加解密--只用于密码
  * @author: lrfalse
  * @date : 2020/1/19 20:23
  **/
public class RC4Util {
	private static String key="es@xLMbK5pBONN*e";

	public static void main(String[] args) throws UnsupportedEncodingException {
		String encryStr = RC4Util.encry("11111111");
		System.out.println("加密后得到得字符串：" + encryStr);
		String decryStr = RC4Util.decry(encryStr);
		System.out.println("解密后得到得字符串：" + decryStr);
	}

	/**
	 * RC4加密，将加密后的数据进行哈希
	 *
	 * @param data     需要加密的数据
	 * @return 返回加密后的数据
	 * @throws UnsupportedEncodingException
	 */
	public static String encry(String data) throws UnsupportedEncodingException {
		return bytesToHex(encryRC4Byte(data, key, "UTF-8"));
	}


	/**
	 * RC4加密，将加密后的字节数据
	 * @param data     需要加密的数据
	 * @param key      加密密钥
	 * @param chartSet 编码方式
	 * @return 返回加密后的数据
	 * @throws UnsupportedEncodingException
	 */
	public static byte[] encryRC4Byte(String data, String key, String chartSet) throws UnsupportedEncodingException {
		if (data == null || key == null) {
			return null;
		}
		if (chartSet == null || chartSet.isEmpty()) {
			byte bData[] = data.getBytes();
			return RC4Base(bData, key);
		} else {
			byte bData[] = data.getBytes(chartSet);
			return RC4Base(bData, key);
		}
	}

	/**
	 * RC4解密
	 * @param data     需要解密的数据
	 * @return 返回解密后的数据
	 * @throws UnsupportedEncodingException
	 */
	public static String decry(String data) throws UnsupportedEncodingException {

		return new String(RC4Base(hexToByte(data), key), "UTF-8");
	}

	//解密
	public static String decryRC4(String data, String key) {
		try {
			if (data == null || key == null) {
				return null;
			}
			return new String(RC4Base(hexToByte(data), key), "UTF-8");

		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

	public static String decryRC4(String data) {
		try {
			if (data == null || key == null) {
				return null;
			}
			return new String(RC4Base(hexToByte(data), key), "UTF-8");

		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * RC4加密初始化密钥
	 *
	 * @param aKey
	 * @return
	 */
	private static byte[] initKey(String aKey) {
		byte[] bkey = aKey.getBytes();
		byte state[] = new byte[256];

		for (int i = 0; i < 256; i++) {
			state[i] = (byte) i;
		}
		int index1 = 0;
		int index2 = 0;
		if (bkey.length == 0) {
			return null;
		}
		for (int i = 0; i < 256; i++) {
			index2 = ((bkey[index1] & 0xff) + (state[i] & 0xff) + index2) & 0xff;
			byte tmp = state[i];
			state[i] = state[index2];
			state[index2] = tmp;
			index1 = (index1 + 1) % bkey.length;
		}
		return state;
	}


	/**
	 * 字节数组转十六进制
	 *
	 * @param bytes
	 * @return
	 */
	public static String bytesToHex(byte[] bytes) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < bytes.length; i++) {
			String hex = Integer.toHexString(bytes[i] & 0xFF);
			if (hex.length() < 2) {
				sb.append(0);
			}
			sb.append(hex);
		}
		return sb.toString();
	}

	/**
	 * 十六进制转字节数组
	 *
	 * @return
	 */
	public static byte[] hexToByte(String inHex) {
		int hexlen = inHex.length();
		byte[] result;
		if (hexlen % 2 == 1) {
			hexlen++;
			result = new byte[(hexlen / 2)];
			inHex = "0" + inHex;
		} else {
			result = new byte[(hexlen / 2)];
		}
		int j = 0;
		for (int i = 0; i < hexlen; i += 2) {
			result[j] = (byte) Integer.parseInt(inHex.substring(i, i + 2), 16);
			j++;
		}
		return result;
	}

	/**
	 * RC4解密
	 *
	 * @param input
	 * @param mKkey
	 * @return
	 */
	private static byte[] RC4Base(byte[] input, String mKkey) {
		int x = 0;
		int y = 0;
		byte key[] = initKey(mKkey);
		int xorIndex;
		byte[] result = new byte[input.length];
		for (int i = 0; i < input.length; i++) {
			x = (x + 1) & 0xff;
			y = ((key[x] & 0xff) + y) & 0xff;
			byte tmp = key[x];
			key[x] = key[y];
			key[y] = tmp;
			xorIndex = ((key[x] & 0xff) + (key[y] & 0xff)) & 0xff;
			result[i] = (byte) (input[i] ^ key[xorIndex]);
		}
		return result;
	}
}